부록 A. 다양한 환경의 자바스크립트
실제 서비스 환경에서 실행되는 JS는 예상과 다르게 동작할 수 있다.
거의 항상 호스팅 환경의 콘텍스트에서 실행되기 때문이다.
A.1 ECMAScript
자바스크립트의 공식 명칭은 ECMAScript다.
Node.js, Rhino 등 브라우저가 아닌 환경에서는 주의할 점이 있다:
0123과 같은 8진수 리터럴이 허용될 수 있다 (느슨한 모드)window.escape()/unescape()사용 가능String.prototype.substrvssubstring구분:
substr의 두 번째 인자는 길이
A.1.1 웹 ECMAScript
브라우저 전용 기능들:
<!--과-->는 한 줄 주석으로 유효함String.prototype메서드 추가:anchor,big,blink,bold,fixed,fontcolor,fontsize,italics,link,small,strike,sub
→ 대부분 사용하지 말 것. DOM API 또는 유틸리티로 대체 가능.
RegExp확장Function.prototype.arguments,caller
→ 비권장, 자제할 것
A.2 호스트 객체
var a = document.createElement('div');
typeof a; // "object"
Object.prototype.toString.call(a); // "[object HTMLDivElement]"
a.tagName; // "DIV"
a는 일반 객체가 아닌 호스트 객체- 내부
[[Class]]값이 다르고, 정의된 프로퍼티 존재
주의할 점:
toString()등 기본 메서드 사용 불가- 덮어쓰기 불가
- 읽기 전용 프로퍼티 존재
this재정의 불가능한 메서드 존재- console도 호스트 객체
A.3 전역 DOM 변수
<div id="foo"></div>
if (typeof foo === "undefined") {
// 실행 안됨
}
console.log(foo); // HTML 요소
- HTML의 id는 전역 변수처럼 작동
- 전역 오염 및 충돌 우려
- 예외 처리 시 신중히 사용
A.4 네이티브 프로토타입
어떤 일이 있어도 네이티브 프로토타입을 확장하지 말 것
Array.prototype.push = function(item) {
this[this.length] = item;
}
주의사항
- 특정 환경에서만 실행된다는 보장이 없다면 확장하지 말자
- 무차별적인 확장은 피하자
if (!Array.prototype.push) {
Array.prototype.push = function() {
// ...
};
}
→ 기존 라이브러리와 충돌하거나 사이드 이펙트 발생 가능
A.4.1 심 / 폴리필
- 구버전 브라우저에 새로운 기능을 추가하는 방법
- 모든 기능이 폴리필로 대체 가능한 것은 아님
결론:
방어 코드와 문서화로 명확히 의도 표현하자.
A.5 <script>들
두 가지 방식:
<script src="..."></script>
<script>...</script>
- 각각은 독립적인 프로그램
- 전역 객체를 통해 변수 공유 가능
- 호이스팅은 불가능
- 에러가 발생해도 다른 스크립트에 영향 없음
var greeting = "Hello world";
var el = document.createElement("script");
el.text = `
function foo() {
alert('greeting');
}
setTimeout(foo, 1000);
`;
document.body.appendChild(el);
A.6 예약어
- JavaScript는 많은 예약어를 가진다
- 향후 확장 가능성을 고려해 사용 자제
A.7 구현 한계
엔진/환경마다 제한 사항이 존재한다:
- 문자열 리터럴 최대 길이
- 함수 인자의 개수/데이터 크기 제한
- 콜 스택 깊이
- 브라우저 실행 블로킹 시간
- 변수명 최대 길이
→ 암기보단 인지하고 있어야 한다.